﻿using System;

namespace LiskovSubstitutionLibrary
{
    public class Purity1 : Purity2
    {
        private object _ownMember;

        private static readonly int[] StaticArrayNew = new int[10];

        private readonly int[] _instanceArray = new int[10];

        public int[] ArrayProperty
        {
            get
            {
                return _instanceArray;
            }
        }

        public Purity3 Purity3 { get; set; }

        public static Purity3 Purity3Static { get; set; }

        private void ModifyStaticField()
        {
            Purity2.StaticField = new object();
        }

        public void PureMethod()
        {
            Console.Write("something");
        }

        public void ModifyOwnMember()
        {
            _ownMember = new object();
        }

        public void ModifyBaseMember()
        {
            BaseMember = new object();
        }

        public void CallModifyOwnMember()
        {
            ModifyOwnMember();
        }

        public void CallModifyOwnMemberIndirect()
        {
            CallModifyOwnMember();
        }

        public void CallModifyOwnBaseMember()
        {
            ModifyOwnBaseField();
        }

        public void CallModifyStaticField()
        {
            ModifyStaticField();
        }

        public void CallModifyStaticFieldIndirect()
        {
            CallModifyStaticField();
        }

        public Purity1 InstanceBuilderMethod(string name)
        {
            ModifyOwnMember();
            Property = name;
            return this;
        }

        public Purity1 InstanceFactoryMethod(string name)
        {
            var purity1 = new Purity1();
            purity1.ModifyOwnMember();
            purity1.Property = name;
            return purity1;
        }

        public Purity1 ModifyFieldOnLocal(string name)
        {
            var purity1 = new Purity1();
            purity1.ModifyOwnMember();
            purity1.BaseMember = name;
            return purity1;
        }

        public static Purity1 StaticFactoryMethod(string name)
        {
            var purity1 = new Purity1();
            purity1.ModifyOwnMember();
            purity1.Property = name;
            return purity1;
        }

        public void StoreElementToInstanceArrayField(int i)
        {
            var random = new Random();
            _instanceArray[random.Next(10)] = i;
        }

        public void StoreElementToInstanceArrayProperty(int i)
        {
            var random = new Random();
            _instanceArray[random.Next(10)] = i;
        }

        public int[] CreateArray()
        {
            return new int[10];
        }

        public void StoreElementToCreatedArray(int i)
        {
            var random = new Random();
            Console.WriteLine((new int[10])[random.Next(10)] = i);
        }

        public void StoreElementToReturnedArray(int i)
        {
            var random = new Random();
            Console.WriteLine(CreateArray()[random.Next(10)] = i);
        }

        public void StoreElementToArgumentArray(int[] parameter, int i)
        {
            var random = new Random();
            Console.WriteLine(parameter[random.Next(10)] = i);
        }

        public void StoreElementToInstanceArray2(int[] parameter, int i)
        {
            var random = new Random();
            Console.WriteLine(_instanceArray[random.Next(10)] = i);
            Console.WriteLine(parameter);
        }

        public void StoreElementToStaticArrayField(int i)
        {
            var random = new Random();
            StaticArrayNew[random.Next(10)] = i;
        }

        public void CallModifyingMethodOnMember()
        {
            Purity3.ModifyingMethod("something");
        }

        public void CallModifyingMethodOnStaticMember()
        {
            Purity3Static.ModifyingMethod("something");
        }

        public void CallModifyingMethodOnArgument(Purity3 p3)
        {
            p3.ModifyingMethod("something");
        }

        public void DontCallModifyingMethodOnArgument(Purity3 p3)
        {
            Purity3.ModifyingMethod("something");
            Console.WriteLine(p3);
        }
    }
}
